유틸리티 타입 정리
유틸리티 타입에 대해 알아보자
2023-10-22
유틸리티 타입은 정의해 놓은 타입을 변환할 때 사용하기 좋은 TypeScript가 제공하는 도구이다. 유틸리티 타입을 쓰지 않더라도 기본 문법으로 타입을 변환할 수 있지만 유틸리티 타입을 사용하면 좀 더 간결하게 타입을 변환할 수 있다.
Partial
Type집합의 모든 프로퍼티를 선택적으로 타입을 변환하는 유틸리티 타입이다.
interface Book {
title: string;
description: string;
author: string;
publisher: string;
}
let typescript: Book = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
}; // 불가능
이 때 Partial
interface Book {
title?: string;
description?: string;
author?: string;
publisher?: string;
}
let typescript: Partial<Book> = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
}; // 가능
14.2 Required
Required
interface Book {
title: string;
description: string;
author?: string;
publisher?: string;
}
let typescript: Book = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
}; // 가능
하지만 Required
interface Book {
title: string;
description: string;
author: string;
publisher: string;
}
let typescript: Required<Book> = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
}; // 불가능
14.3 Readonly
Type의 모든 프로퍼티를 재할당이 불가능한 읽기 전용(Readonly) 으로 설정한 타입을 생성한다.
읽기 전용(Readonly)가 아니면 재할당이 가능하다.
interface Book {
title: string;
description: string;
author?: string;
publisher?: string;
}
let typescript: Book = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
};
typescript.title = "TypeScript Basic"; // 재할당 가능
하지만 Readonly
interface Book {
readonly title: string;
readonly description: string;
readonly author?: string;
readonly publisher?: string;
}
let typescript: Readonly<Book> = {
title: "알잘딱깔센 TypeScript",
description: "타입스크립트 입문자가 읽으면 좋은 책",
};
typescript.title = "TypeScript Basic"; // 재할당 불가능
14.4 Record<Keys, Type>
프로퍼티 타입을 Key로, value 타입을 Type으로 지정해 생성한다. Record<Keys,Type> 유틸리티 타입은 프로퍼티를 다른 타입으로 매핑하고 싶을 때 사용하면 좋다.
interface Food {
"1팀": "피자" | "치킨" | "햄버거" | "컵라면";
"2팀": "피자" | "치킨" | "햄버거" | "컵라면";
"3팀": "피자" | "치킨" | "햄버거" | "컵라면";
"4팀": "피자" | "치킨" | "햄버거" | "컵라면";
}
const food: Food = {
"1팀": "피자",
"2팀": "치킨",
"3팀": "햄버거",
"4팀": "컵라면",
};
value 값의 반복이 보인다. 이를 Record<Keys,Type>을 활용하면 해결할 수 있다.
const food: Record<
"1팀" | "2팀" | "3팀" | "4팀",
"피자" | "치킨" | "햄버거" | "컵라면"
> = {
"1팀": "피자",
"2팀": "치킨",
"3팀": "햄버거",
"4팀": "컵라면",
};
훨씬 간결해진 모습이지만 조금 길어 보인다. 이를 type을 활용해 정리해 줄 수 있다.
type Team = "1팀" | "2팀" | "3팀" | "4팀";
type Food = "피자" | "치킨" | "햄버거" | "컵라면";
const food: Record<Team, Food> = {
"1팀": "피자",
"2팀": "치킨",
"3팀": "햄버거",
"4팀": "컵라면",
};
type을 활용해 정리해 주면 재사용에 용이하다.
Pick<Type, Keys>
Type에서 프로퍼티 Keys를 Pick(선택)해 타입을 생성한다.
아래 예제는 Person에서 name과 age를 선택해 kim을 생성한다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
const kim: Pick<Person, "name" | "age"> = {
name: "Kim",
age: 27,
};
만약 name과 age가 아닌 다른 key를 선택하게 되면 에러가 발생한다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
const kim: Pick<Person, "name" | "age"> = {
name: "Kim",
location: "Jeju", // Error: Type '{ name: string; location: string; }' is not assignable to type 'Pick<Person, "name" | "age">'
Pick<Type,Keys> 유틸리티 역시 type을 사용해 정리할 수 있다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
type Kim = Pick<Person, "name" | "age">;
const kim: Kim = {
name: "Kim",
age: 27,
};
Omit<Type, Keys>
Pick 유틸리티 타입과는 반대 개념으로 Type에서 프로퍼티 Keys를 Omit(생략)해 타입을 생성한다.
아래 예제는 Person에서 age와 gender를 생략해 kim을 생성한다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
const kim: Omit<Person, "age" | "gender"> = {
name: "Kim",
location: "Jeju",
};
만약 age나 gender를 포함하게 되면 에러가 발생한다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
const kim: Omit<Person, "age" | "gender"> = {
name: "Kim",
location: "Jeju",
gender: "M", // Error: Type '{ name: string; location: string; gender: string; }' is not assignable to type 'Omit<Person, "age" | "gender">'
};
Omit<Type,Keys> 유틸리티 역시 type을 사용해 정리할 수 있다.
interface Person {
name: string;
age: number;
location: string;
gender: "M" | "W";
}
type Kim = Omit<Person, "age" | "gender">;
const kim: Kim = {
name: "Kim",
location: "Jeju",
};
Exclude<Type, ExcludeUnion>
ExcludeUnion에 들어갈 수 있는 모든 유니온을 Type에서 제외한 타입을 생성한다.
type T1 = Exclude<"kim" | "lee" | "park", "park">;
// result : type T1 = "kim" | "lee"
type T2 = Exclude<string | number | boolean, number | boolean>;
// result : type T2 = string
type T1에서 "park" 을 제외한 "kim" | "lee"가 남게 된다. type T2 역시 number와 boolean 을 제외한 string이 남게 된다.
type T1 = Exclude<string | number | boolean, number>;
// result : type T1 = string | boolean
type T2 = Exclude<T1, boolean>;
// result : type T2 = string
14.6 NonNullable
Type에서 null과 undefined를 제외하고 타입을 생성한다.
type T1 = NonNullable<string | number | boolean | null | undefined>;
// result : type T1 = string | number | boolean
T1 에서 null과 undefined을 제외한 string과 number, boolean이 남게 된다.